#include <Python.h>
#include <numpy/arrayobject.h>
#include <cassert>
#include <iostream>
#include <cstdlib>
#include <string>
#include "Video.h"
#include "./../Complejos/Complejo.h"

using namespace std;

void hacerFractal(int* matriz, long double x1, long double x2, long double y1, long double y2);
int calcularMandel(long double re, long double im, int iter);
int calcularMandel(Complex c, int iter);

int main(int argc, char *argv[]) {
	char * path = "";
	if (argc ==1){
		path = argv[1];
	} 
	Video video = *(new Video ((long)512, (long)512));
	int* matriz = video.matriz();
	for(int fila = 0; fila < 512; fila++){
		for(int col = 0; col < 64; col++){
			int valor = fila/2;
			matriz[fila*512 + col] = valor;
			matriz[fila*512 + col] +=  valor<<8;
			matriz[fila*512 + col] +=  valor<<16;
		}
		for(int col = 64; col < 128; col++){
			int valor = fila/2;
			matriz[fila*512 + col] = valor;
		}
		for(int col = 128; col < 192; col++){
			int valor = fila/2;
			matriz[fila*512 + col] =  valor<<8;
		}
		for(int col = 192; col < 256; col++){
			int valor = fila/2;
			matriz[fila*512 + col] =  valor<<16;
		}
		for(int col = 256; col < 320; col++){
			int valor = fila/2;
			matriz[fila*512 + col] = valor;
			matriz[fila*512 + col] +=  valor<<8;
		}
		for(int col = 384; col < 448; col++){
			int valor = fila/2;
			matriz[fila*512 + col] = valor;
			matriz[fila*512 + col] +=  valor<<16;
		}
		for(int col = 448; col < 512; col++){
			int valor = fila/2;
			matriz[fila*512 + col] = valor<<16;
			matriz[fila*512 + col] +=  valor<<8;
		}
		for(int col = 320; col < 384; col++){
			int valor = fila/2;
			matriz[fila*512 + col] = 0;
		}
	}
	video.refresh();
	
//	long double x1 = -2;
//	long double x2 = 2;
//	long double y1 = -2;
//	long double y2 = 2;
//	hacerFractal(matriz,-2,2,-2,2);
//	video.refresh();
//	int pos[2];
//	video.waitForClick(pos);
//	while(true) {
////		cout << "X: " << pos[0] << " Y: " << pos[1] << endl;
//		x1 = x1 + ((long double)pos[0]*(x2-x1)/512);
//		y1 = y1 + ((long double)pos[1]*(x2-x1)/512);
//		x1-=2;
//		y1-=2;
//		x2=x1+4;
//		y2=y1+4;
////		cout << "EN EL PLANO X: " << x1 << endl;
//		if(pos[0] <= 10)
//			break;
//		cout << "DIBUJANDO" << endl;
//		hacerFractal(matriz,x1,x2,y1,y2);
//		cout << "FIN" << endl;
//		video.refresh();
//		video.waitForClick(pos);
//	}
	PyRun_SimpleString ("time.sleep(5)");
	return 0;
}

void hacerFractal(int* matriz, long double x1, long double x2, long double y1, long double y2) {
	Complex comp(x1,y1);
	long double ex = (x2-x1)/512;
	long double ey = (y2-y1)/512;
	int r=0;
	int c=0;
	while(comp.Im() < y2) {
		while(comp.Re() < x2) {
			int i = calcularMandel(comp,1020);
			//write the point nicely colored to the bitmap
			//cout << x << endl;
			long long int valor = 0xFF000000;
			if (i<100) {
				valor += (255-(i/4))*256*256;	//r
				valor += (255-(i/4))*256;	//g
				valor += (255-(i/4));		//b
			} else if (i<800) {
				valor += 255*256*256;	//r
				valor += 0;	//g
				valor += 0;			//b
			} else {
				valor += (255-(i/4))*256*256;	//r
				valor += (255-(i/4))*256;	//g
				valor += (255-(i/4));		//b
			}
			matriz[r+c*512] = valor;
			c++;
			Complex aux(ex,0);
			comp = comp+aux;
			if(r+c*512 < 0 || r+c*512 > 262144)
				assert("NOOOOOOOOOOOOO");
		}
		c=0;
		r++;
		Complex aux(-2*comp.Re(),ey);
		comp = comp+aux;
	}
}

int calcularMandel(long double re, long double im, int iter) {
    int it = 0;
    long double auxRe = 0;
    long double auxIm = 0;
    long double cuad = re*re + im*im;
    while(it<iter && cuad <= 4) {
        long double aux = (auxRe+auxIm)*(auxRe-auxIm) + re;
        auxIm = 2*auxRe*auxIm + im;
        auxRe = aux;
        cuad = auxRe*auxRe+auxIm*auxIm;
        it++;
    }
    return it;
}

int calcularMandel(Complex c, int iter) {
    Complex a(0,0);
    int it = 0;
    while(it<iter && a.moduloModulo() <= 4) {
        a = a*a;
        a = a+c;
        it++;
    }
    return it;
}

